package team.seekers.hula.record.mind.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.common.entity.enums.MindTypeEnum;
import team.seekers.hula.record.mind.entity.dto.MindUpdateDTO;
import team.seekers.hula.auth.service.MindUtils;
import team.seekers.hula.record.mind.entity.dao.MindDO;
import team.seekers.hula.record.mind.mapper.MindMapper;
import team.seekers.hula.question.question.service.QuestionService;
import team.seekers.hula.user.user.entity.dao.UserDO;
import team.seekers.hula.record.mind.entity.dto.MindQueryDTO;
import team.seekers.hula.record.mind.entity.vo.MindListVO;
import team.seekers.hula.question.question.entity.vo.QuestionMindListVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import team.seekers.hula.user.userFollow.service.UserFollowerService;
import team.seekers.hula.user.user.service.UserService;

import java.util.*;

import static team.seekers.hula.common.entity.enums.MindTypeEnum.ADD_NORMAL;

/**
 * 一个输出，可以是提出一个问题、提出一个观点、写出一个回答、写一个mind 服务实现类
 * @author hbc
 * @since 2021-02-15
 */
@Service
public class MindService extends ServiceImpl<MindMapper, MindDO> {

    @Autowired
    @Lazy
    private QuestionService questionService;
    @Autowired
    @Lazy
    private UserFollowerService userFollowerService;
    @Autowired
    @Lazy
    private UserService userService;

    //动作改变维护表
    public String addQuestion(String questionId,Integer visibility) {
        MindDO mindDO = new MindDO();
        mindDO.setUserId(MindUtils.getUserId());
        mindDO.setVisibility(visibility);
        mindDO.setLinkId(questionId);
        mindDO.setType(MindTypeEnum.ADD_QUESTION);
        save(mindDO);
        return mindDO.getId();
    }

    public String addPoint(String pointId,Integer visibility) {
        MindDO mindDO = new MindDO();
        mindDO.setUserId(MindUtils.getUserId());
        mindDO.setVisibility(visibility);
        mindDO.setLinkId(pointId);
        mindDO.setType(MindTypeEnum.ADD_POINT);
        save(mindDO);
        return mindDO.getId();
    }

    public String addAnswer(String answerId,Integer visibility) {
        MindDO mindDO = new MindDO();
        mindDO.setUserId(MindUtils.getUserId());
        mindDO.setVisibility(visibility);
        mindDO.setLinkId(answerId);
        mindDO.setType(MindTypeEnum.ADD_ANSWER);
        save(mindDO);
        return mindDO.getId();
    }

    public MindListVO addNormal(String content,Integer visibility) {
        MindDO mindDO = new MindDO();
        mindDO.setUserId(MindUtils.getUserId());
        mindDO.setVisibility(visibility);
        mindDO.setContent(content);
        mindDO.setType(ADD_NORMAL);
        save(mindDO);

        MindListVO mindListVO = new MindListVO();
        BeanUtils.copyProperties(mindDO,mindListVO);
        mindListVO.setType(mindDO.getType().getType());

        return mindListVO;
    }

    public void updateVisibilityByLinkId(String linkId,Integer visibility) {
        lambdaUpdate().set(MindDO::getVisibility,visibility).eq(MindDO::getLinkId,linkId).update();
    }

    public void deleteMindByLinkId(String linkId) {
        QueryWrapper<MindDO> wrapper = new QueryWrapper<>();
        wrapper.eq("link_id",linkId);
        remove(wrapper);
    }

    public void deleteMindByLinkIds(List<String> linkIds) {
        QueryWrapper<MindDO> wrapper = new QueryWrapper<>();
        wrapper.in("link_id",linkIds);
        remove(wrapper);
    }


    public void delete(String id) {
        // 级联删除绑定的mind内容


        removeById(id);
    }

    public PageResult<MindListVO> pageOrderByTime(MindQueryDTO mindQueryDTO) {
        Page<MindDO> page = new Page<>(mindQueryDTO.getPageNow(),mindQueryDTO.getPageSize());
        QueryWrapper<MindDO> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", mindQueryDTO.getUserId());
        if(mindQueryDTO.getType() != null && mindQueryDTO.getType() != 0)
            wrapper.eq("type", mindQueryDTO.getType());

        if(mindQueryDTO.getVisibility() != null){
            wrapper.eq("visibility", mindQueryDTO.getVisibility());
        }

        wrapper.orderByDesc("gmt_create");

        page(page, wrapper);

        if(page.getTotal() == 0){
            return new PageResult<>();
        }

        return new PageResult<>(page.getTotal(),DOListToVOList(page.getRecords()));
    }

    public PageResult<MindListVO> pageFocusOrderByTime(MindQueryDTO mindQueryDTO) {
        LambdaQueryChainWrapper<MindDO> mindWrapper = lambdaQuery().orderByDesc(MindDO::getGmtCreate);
        if(mindQueryDTO != null){
            String begin = mindQueryDTO.getBegin();
            if(!StringUtils.isEmpty(begin)){
                mindWrapper.ge(MindDO::getGmtCreate,begin);
            }
            String end = mindQueryDTO.getEnd();
            if (!StringUtils.isEmpty(end)){
                mindWrapper.le(MindDO::getGmtCreate,end);
            }
            if (!StringUtils.isEmpty(mindQueryDTO.getUserId())){
                mindWrapper.eq(MindDO::getUserId,mindQueryDTO.getUserId());
            }
        }
        // 把关注的所有人的id代入
        List<String> listAllFocusId = userFollowerService.listAllFocusId(MindUtils.getUserId());
        if(listAllFocusId.size() == 0){
            return new PageResult<>(0,new ArrayList<MindListVO>());
        }
        mindWrapper.in(MindDO::getUserId,listAllFocusId);

        Page<MindDO> page = mindWrapper.page(new Page<>(mindQueryDTO.getPageNow(), mindQueryDTO.getPageSize()));

        if(page.getTotal() == 0){
            return new PageResult<>();
        }
        return new PageResult<>(
                page.getTotal(),
                DOListToVOList(page.getRecords()));
    }

    private List<MindListVO> DOListToVOList(List<MindDO> DOList){
        List<MindListVO> list = new ArrayList<>();
        for (MindDO record : DOList) {
            MindListVO mindListVO = new MindListVO();
            BeanUtils.copyProperties(record,mindListVO);
            mindListVO.setId(record.getId());
            mindListVO.setType(record.getType().getValue());
            mindListVO.setGmtCreate(record.getGmtCreate());
            QuestionMindListVO questionMindListVO;
            switch (record.getType()){
                case ADD_QUESTION:
                    questionMindListVO = questionService.getMindListVOByQuestionId(record.getLinkId());
                    if(questionMindListVO == null){
                        return null;
                    }
                    mindListVO.setQuestionListVO(questionMindListVO);
                    break;
                case ADD_POINT:
                    questionMindListVO = questionService.getMindListVOByPointId(record.getLinkId());
                    if(questionMindListVO == null){
                        return null;
                    }
                    mindListVO.setQuestionListVO(questionMindListVO);
                    break;
                case ADD_ANSWER:
                    questionMindListVO = questionService.getMindListVOByAnswerId(record.getLinkId());
                    if(questionMindListVO == null){
                        return null;
                    }
                    mindListVO.setQuestionListVO(questionMindListVO);
                    break;
                case ADD_NORMAL:
                    mindListVO.setContent(record.getContent());
                    break;
            }
            UserDO byId = userService.getById(mindListVO.getUserId());
            if (byId == null){
                return null;
            }
            mindListVO.setUserId(byId.getId());
            mindListVO.setNickname(byId.getNickname());
            mindListVO.setAvatar(byId.getAvatar());
            list.add(mindListVO);
        }

        return list;
    }


    public void updateNormal(MindUpdateDTO updateDTO) {
        lambdaUpdate().set(MindDO::getContent,updateDTO.getContent()).eq(MindDO::getId,updateDTO.getId()).update();
    }
}
